using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace Crap4Net.CCParsers
{
    public class NCoverMethodParser
    {
        public MethodSignature ParseMethodSignature(XElement method)
        {
            string assembly = GetAssemblyName(method);
            string nameSpace = GetNameSpace(method);
            string typeName = GetTypeNameWithoutNameSpace(method);
            string methodName = GetMethodName(method);
            string[] args = GetArgs(method);
            var methodSignature = new MethodSignature(assembly, nameSpace, typeName, methodName, args);
            return methodSignature;
        }

        private string GetAssemblyName(XElement method)
        {
            var moduleElem = GetModuleElem(method);
            return (string)moduleElem.Attribute("assembly");
        }

        private XElement GetModuleElem(XElement method)
        {
            return method.Parent.Parent;
        }

        private string GetNameSpace(XElement method)
        {
            var classElem = method.Parent;
            var fullClassName = (string)classElem.Attribute("name");
            int end = fullClassName.LastIndexOf('.');
            if (end == -1) //no namespace
                return "";
            return fullClassName.Substring(0, end);
        }

        private string GetTypeNameWithoutNameSpace(XElement method)
        {
            var classElem = method.Parent;
            var fullClassName = (string)classElem.Attribute("name");
            int start = fullClassName.LastIndexOf('.');
            return fullClassName.Substring(start + 1, fullClassName.Length - 1 - start);
        }

        private string GetMethodName(XElement method)
        {
            var fullName = (string)method.Attribute("signature");
            int end = fullName.LastIndexOf('(');
            return fullName.Substring(0, end);

        }

        private string[] GetArgs(XElement method)
        {
            var fullMethodName = (string)method.Attribute("signature");
            int start = fullMethodName.IndexOf('(');
            int end = fullMethodName.IndexOf(')');
            var argString = fullMethodName.Substring(start + 1, end - start - 1);
            if (string.IsNullOrEmpty(argString))
                return new string[] { };
            else
                return RemoveNames(argString.Split(new char[] { ',' }));
        }

        private string[] RemoveNames(string[] paramsWithNames)
        {
            var result = new List<string>();
            foreach (var param in paramsWithNames)
            {
                result.Add(param.Split(new char[] { ' ' })[0]);
            }
            return result.ToArray();
        }
    }
}
